import * as Cesium from '@cesium/Source/Cesium.js';
import * as echarts from 'echarts';

// 原文链接：https://blog.csdn.net/qq_34205305/article/details/105627925

/*
 * @Author: Wang JianLei
 * @Date: 2020-04-08 10:55:43
 * @Last Modified by: Wang JianLei
 * @Last Modified time: 2020-04-20 09:49:37
*/

//剖面分析
/******************************************* **
剖面分析直接调用Profile()即可，左键画线，右键停止
createProfileChart()方法绘制剖面图
** ****************************************** */
var terrainProfile = function(viewer, domChart, vm) {
  const scene = viewer.scene;
  var handler = new Cesium.ScreenSpaceEventHandler(scene._imageryLayerCollection);
  var positions = [];
  var positionsCartographic = [];
  var positions_Inter = [];
  var poly = null;
  var distance = 0;
  var cartesian = null;
  var floatingPoint;
  var DistanceArray = [];

  var profileItem = [];

  // let $menuBox = $('#SideBar');
  // let outerW = $menuBox.outerWidth();
  handler.setInputAction(function(movement) {
    // movement.endPosition.x = movement.endPosition.x - outerW;
    if (positions.length >= 2) {
      if (!Cesium.defined(poly)) {
        poly = new PolyLinePrimitive(positions);
      } else {
        positions.pop();
        cartesian = scene.pickPosition(movement.endPosition);
        positions.push(cartesian);
      }
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

  handler.setInputAction(function(movement) {
    // movement.position.x = movement.position.x - outerW;
    cartesian = scene.pickPosition(movement.position);
    if (positions.length == 0) {
      positions.push(cartesian.clone());
    }
    positions.push(cartesian);
    if (poly) {
      //进行插值计算
      interPoints(poly.positions);
      distance = getSpaceDistance(positions_Inter);
    } else {
      distance = getSpaceDistance(positions);
    }
    var textDisance = distance + "米";
    DistanceArray.push(distance);
    floatingPoint = viewer.entities.add({
      position: positions[positions.length - 1],
      point: {
        pixelSize: 5,
        color: Cesium.Color.RED,
        outlineColor: Cesium.Color.WHITE,
        outlineWidth: 2,
        heightReference: Cesium.HeightReference.NONE
      },
      label: {
        text: textDisance,
        font: '18px sans-serif',
        fillColor: Cesium.Color.GOLD,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        outlineWidth: 2,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        pixelOffset: new Cesium.Cartesian2(20, -20),
        heightReference: Cesium.HeightReference.NONE
      }
    });
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

  handler.setInputAction(function(movement) {
    handler.destroy(); //关闭事件句柄
    positions.pop(); //最后一个点无效
    createProfileChart(profileItem, domChart);
    vm.showChart = true
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

  var PolyLinePrimitive = (function() {
    function _(positions) {
      this.options = {
        polyline: {
          show: true,
          positions: [],
          material: Cesium.Color.CHARTREUSE,
          width: 3,
          clampToGround: true
        }
      };
      this.positions = positions;
      this._init();
    }
    _.prototype._init = function() {
      var _self = this;
      var _update = function() {
        return _self.positions;
      };
      //实时更新polyline.positions
      this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
      viewer.entities.add(this.options);
    };
    return _;
  })();

  function cartesian3ToDegrees(position) {
    const {
      height,
      latitude,
      longitude,
    } = Cesium.Cartographic.fromCartesian(position);
    return [longitude, latitude, height]
  }

  //空间两点距离计算函数
  function getSpaceDistance(positions) {
    profileItem = [{
      point: cartesian3ToDegrees(positions[0]),
      distance: 0
    }];
    var distance = 0;
    for (var i = 0; i < positions.length - 1; i++) {

      var point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
      var point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);
      /**根据经纬度计算出距离**/
      var geodesic = new Cesium.EllipsoidGeodesic();
      geodesic.setEndPoints(point1cartographic, point2cartographic);
      var s = geodesic.surfaceDistance;
      //返回两点之间的距离
      s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
      distance = distance + s;
      var m_Item = {
        point: cartesian3ToDegrees(positions[i + 1]),
        distance: distance
      };
      profileItem.push(m_Item);
    }
    return distance.toFixed(2);
  }

  //线段插值点
  function interPoints(positions) {
    positionsCartographic = [];
    var terrainSamplePositions = [];
    for (let index = 0; index < positions.length - 1; index++) {
      const element = positions[index];
      var ellipsoid = viewer.scene.globe.ellipsoid;
      var cartographic = ellipsoid.cartesianToCartographic(element);
      positionsCartographic.push(cartographic);
    }
    for (let i = 0; i < positionsCartographic.length; i++) {
      const m_Cartographic0 = positionsCartographic[i];
      const m_Cartographic1 = positionsCartographic[i + 1];
      if (m_Cartographic1) {
        var a = Math.abs(m_Cartographic0.longitude - m_Cartographic1.longitude) * 10000000;
        var b = Math.abs(m_Cartographic0.latitude - m_Cartographic1.latitude) * 10000000;
        //等距采样
        if (a > b) b = a;
        var length = parseInt(b / 2);
        if (length > 100) length = 100;
        if (length < 2) length = 2;
        // var length = 4;//等分采样
        for (var j = 0; j < length; j++) {
          terrainSamplePositions.push(
            new Cesium.Cartographic(
              Cesium.Math.lerp(m_Cartographic0.longitude, m_Cartographic1.longitude, j / (length - 1)),
              Cesium.Math.lerp(m_Cartographic0.latitude, m_Cartographic1.latitude, j / (length - 1))
            )
          );
        }
        terrainSamplePositions.pop();
      } else {
        terrainSamplePositions.push(m_Cartographic0);
      }
    }
    positions_Inter = [];
    for (var n = 0; n < terrainSamplePositions.length; n++) {
      //地理坐标（弧度）转经纬度坐标
      var m_cartographic = terrainSamplePositions[n];
      var height = viewer.scene.globe.getHeight(m_cartographic);
      var point = Cesium.Cartesian3.fromDegrees(m_cartographic.longitude / Math.PI * 180, m_cartographic.latitude /
        Math.PI * 180, height);
      positions_Inter.push(point);
    }
  }
};

/*
 * @Author: Wang JianLei
 * @Date: 2020-04-20 10:47:46
 * @Last Modified by: Wang JianLei
 * @Last Modified time: 2020-04-20 10:48:27
 */
//Echart绘制剖面图
/******************************************* **
调用分析结果createProfileChart()方法绘制剖面图
** ****************************************** */
function createProfileChart(Positions, dom) {
  // console.log(Positions);
  var x_Range = parseInt(Positions[Positions.length - 1].distance);
  // console.log(x_Range);
  var ProfileData = [];
  var ProfileData_Lon = [];

  var y_Min = 100000000;
  for (let index = 0; index < Positions.length; index++) {
    const element = Positions[index];
    var m_distance = element.distance.toFixed(2);
    var m_Lon = element.point[0].toFixed(5);
    var m_Lat = element.point[1].toFixed(5);
    var m_height = element.point[2].toFixed(2);
    if (m_height < y_Min) {
      y_Min = m_height;
    }
    var m_data = [m_distance, m_height, m_Lon, m_Lat];
    ProfileData.push(m_data);
    ProfileData_Lon.push([m_Lon, m_Lat]);
  }
  // console.log(ProfileData);
  var lineChart = echarts.init(dom, 'dark');
  // background: rgba(255, 255, 255, 1);
  var lineoption = {
    title: {
      text: '剖面分析'
    },
    grid: {
      left: 0,
      right: 25,
      top: 50,
      bottom: 10,
      containLabel: true
    },
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross'
      },
      padding: [5, 10],
      formatter: function(arr) {
        var a = '';
        if (0 == arr.length) return a;
        let e = arr[0];
        var data = e.data;
        const html = `位置&nbsp;${data[2]},${data[3]}<br/>距起点&nbsp;
            <label>${e.axisValueLabel}米</label><br/>
            ${e.seriesName}&nbsp;<label style='color:${e.color};'>${data[1]}米</label><br />`
        return html
      }
    },
    calculable: true,
    xAxis: [{
      type: 'value',
      max: 'dataMax',
      // type: 'category',
      boundaryGap: true,
      axisLine: {
        show: true
      },
      axisLabel: {
        show: true
      },
      // scale: true
    }],
    yAxis: [{
      type: 'value',
      min: y_Min,
      axisLabel: {
        // rotate: 60,
        formatter: '{value} 米'
      },
      // scale: true
    }],
    series: [{
      name: '高程',
      type: 'line',
      data: ProfileData,
      symbol: "none",
      itemStyle: {
        normal: {
          color: 'rgb(255, 70, 131)'
        }
      },
      lineStyle: {
        width: 1
      },
      markPoint: {
        data: [{
            type: 'max',
            name: '最高点'
          },
          {
            type: 'min',
            name: '最低点'
          }
        ]
      }
    }]
  };
  lineChart.setOption(lineoption);

  //    document.getElementById("profileChart").style.backgroundColor = 'rgba(255, 255, 255, 1)';
  //    document.getElementById("profileChart").style.visibility = 'visible';
  //    $(window).resize(lineChart.resize);
}

export {
  terrainProfile,
  createProfileChart
}
